import { contextMenu } from './context-menu-config';
import { cloneDeep } from 'lodash-es';
import { RowNode } from '@farris/ui-treetable';
import { ContextMenuManager } from '../../../../service/context-menu.manager';
import { ControlContextMenuItem } from '../../../../entity/control-context-menu';
import { FarrisDesignBaseComponent } from '@farris/designer-element';
import { MessagerService } from '@farris/ui-messager';
import { BsModalService } from '@farris/ui-modal';
import { ComponentFactoryResolver } from '@angular/core';
import { DgControl } from '../../../../utils/dg-control';
import { ListFilterFieldsEditorComponent } from '../../list-filter/property/editor/list-filter-fields-editor/list-filter-fields-editor.component';
import { ListFilterBuilderService } from '../../list-filter/context-menu/filter-builder';
import { QuerySchemeBuilderService } from './query-scheme-builder';

const CHANGE_TO_LISTFILTER_COMMAND = 'changeToListFilter';

export class QuerySchemeContextMenuManager extends ContextMenuManager {

    private msgService: MessagerService;
    private modalService: BsModalService;
    private resolver: ComponentFactoryResolver;

    /** 筛选方案外层容器Id */
    querySchemeContainerId: string;

    /** 筛选条所在的列表组件 */
    listFilterDataGridComponent: any;

    constructor(cmp: FarrisDesignBaseComponent, rowNode: RowNode) {
        super(cmp, rowNode);

        this.msgService = this.injector.get(MessagerService);
        this.resolver = this.injector.get(ComponentFactoryResolver);
        this.modalService = this.injector.get(BsModalService);

    }
    /**
     * 过滤、修改控件树右键菜单
     */
    setContextMenuConfig() {
        let menuConfig = cloneDeep(contextMenu) as ControlContextMenuItem[];

        menuConfig = this.assembleChangeToListFilterMenu(menuConfig);


        // 配置菜单点击事件
        this.addContextMenuHandle(menuConfig);

        return menuConfig || [];
    }

    /**
     * 点击控件树右键菜单
     */
    contextMenuClicked(e: { data: RowNode, menu: ControlContextMenuItem }) {

        const menu = e.menu;
        switch (menu.id) {
            case 'changeToListFilter': {
                this.openListFilterModal();
                break;
            }
            case 'removeQueryScheme': {
                this.removeQueryScheme();
                break;
            }
            default: {
                this.notifyService.warning('暂不支持');
            }
        }

    }


    assembleChangeToListFilterMenu(menuConfig: ControlContextMenuItem[]) {
        const changeToListFilterMenu = menuConfig.find(menu => menu.id === CHANGE_TO_LISTFILTER_COMMAND);
        if (!changeToListFilterMenu) {
            return menuConfig;
        }
        this.getListFilterDataGridComponent();

        // 当前模板若不能启用筛选条，则移除菜单
        if (!this.listFilterDataGridComponent) {
            menuConfig = menuConfig.filter(menu => menu.id !== CHANGE_TO_LISTFILTER_COMMAND);
            return menuConfig;
        }

        // 若列表组件已有筛选条，则移除菜单
        const listFilterNode = this.domService.selectNode(this.listFilterDataGridComponent, item => item.type === DgControl.ListFilter.type);
        if (listFilterNode) {
            menuConfig = menuConfig.filter(menu => menu.id !== CHANGE_TO_LISTFILTER_COMMAND);
            return menuConfig;
        }

        // 筛选方案外层没有模板预置的容器，则不支持切换筛选条
        const querySchemeContainerId = this.cmpInstance.parent.id;
        const querySchemeContainerNode = this.domService.domDgMap.get(querySchemeContainerId);
        if (querySchemeContainerNode.type !== DgControl.Section.type || !querySchemeContainerNode.appearance ||
            !querySchemeContainerNode.appearance.class || !querySchemeContainerNode.appearance.class.includes('f-section-scheme')) {

            // console.log('未检测到筛选方案容器');
            menuConfig = menuConfig.filter(menu => menu.id !== CHANGE_TO_LISTFILTER_COMMAND);
            return menuConfig;
        }

        this.querySchemeContainerId = querySchemeContainerId;
        return menuConfig;
    }

    /**
     * 定位到可以启用筛选条的列表组件
     */
    private getListFilterDataGridComponent() {
        this.listFilterDataGridComponent = null;
        const templateOutlineSchema = this.domService.templateOutlineSchema || [];
        const listFilterConfig = templateOutlineSchema.find(schema => schema.listFilter && schema.listFilter.canEnable);
        if (!listFilterConfig) {
            return;
        }

        const rootComponent = this.domService.getComponentById('root-component');
        let dataGridContainerNode;
        if (typeof (listFilterConfig.path) === 'string') {
            dataGridContainerNode = this.domService.getNodeByIdPath(rootComponent, listFilterConfig.path as string);
        } else {
            for (const path of listFilterConfig.path) {
                dataGridContainerNode = this.domService.getNodeByIdPath(rootComponent, path as string);
                if (dataGridContainerNode) {
                    break;
                }
            }
        }

        if (!dataGridContainerNode) {
            return;
        }

        const allComponentRefs = [];
        this.selectAllNodes(dataGridContainerNode, item => item.type === DgControl.ComponentRef.type, allComponentRefs);
        for (const refNode of allComponentRefs) {
            const dataGridRef = this.domService.components.find(co =>
                co.id === refNode.component && co.componentType === 'dataGrid');
            if (dataGridRef) {
                this.listFilterDataGridComponent = dataGridRef;
                return;
            }
        }
    }
    /**
     * 根据指定的条件遍历查找节点
     * @param rootNode 容器节点
     * @param predict 条件
     */
    private selectAllNodes(rootNode: any, predict: (item: any) => boolean, targetNodes: any[]) {
        if (!rootNode) {
            return;
        }
        if (predict(rootNode)) {
            targetNodes.push(rootNode);
            return;
        }
        if (rootNode.contents) {
            for (const item of rootNode.contents) {
                this.selectAllNodes(item, predict, targetNodes);
            }
        }
        return;
    }
    private openListFilterModal() {

        this.msgService.question('确定切换为筛选条？', () => {

            const compFactory = this.resolver.resolveComponentFactory(ListFilterFieldsEditorComponent);
            const compRef = compFactory.create(this.injector);

            const modalConfig = {
                title: '筛选条字段编辑器',
                width: 950,
                height: 500,
                showButtons: true,
                showMaxButton: true,
                buttons: compRef.instance.modalFooter
            };
            compRef.instance.value = [];
            compRef.instance.editorParams = {
                viewModelId: this.listFilterDataGridComponent.viewModel,
                controlSource: 'normal'
            };
            compRef.instance.showPropertyPanel = false;
            const modalPanel = this.modalService.show(compRef, modalConfig);
            compRef.instance.closeModal.subscribe(() => {
                modalPanel.close();
            });
            compRef.instance.submitModal.subscribe((data) => {
                if (data && data.value) {
                    const filterBuilderService = new ListFilterBuilderService(this.injector);

                    // 1、创建筛选条
                    const dataGridNode = this.domService.selectNode(this.listFilterDataGridComponent,
                        item => item.type === DgControl.DataGrid.type);
                    filterBuilderService.createListFilterInDocument(data.value, this.listFilterDataGridComponent.viewModel, dataGridNode.id);
                    this.notifyService.success('启用成功');

                    // 2、移除筛选方案
                    const querySchemBuilderSerive = new QuerySchemeBuilderService(this.injector);
                    querySchemBuilderSerive.removeQuerySchemeInDocument();

                    this.cmpInstance.emit('clearPropertyPanel');
                    this.refreshFormService.refreshFormDesigner.next();
                }
                modalPanel.close();
            });
        });

    }

    /**
     * 移除筛选方案
     */
    removeQueryScheme() {
        this.msgService.question('确定移除筛选方案？', () => {

            const viewModelId = this.cmpInstance.viewModelId;
            const schemeId = this.cmpInstance.id;

            // 1、清除筛选方案DOM和配套的父级Section容器的DOM 结构
            const component = this.domService.getComponentByVMId(viewModelId);
            const sectionContainerNode = this.domService.getControlParentById(component, schemeId);

            if (sectionContainerNode.type !== DgControl.Section.type || !sectionContainerNode.appearance ||
                !sectionContainerNode.appearance.class || !sectionContainerNode.appearance.class.includes('f-section-scheme')) {

                sectionContainerNode.contents = sectionContainerNode.contents.filter(c => c.id !== schemeId);
            } else {
                const sectionContainerParentNode = this.domService.getControlParentById(component, sectionContainerNode.id);

                sectionContainerParentNode.contents = sectionContainerParentNode.contents.filter(c => c.id !== sectionContainerNode.id);
            }

            // 移除根节点对应的样式
            const rootComponentJson = this.domService.getComponentById('root-component');
            const templateOutlineSchema = this.domService.templateOutlineSchema || [];
            const schemeConfig = templateOutlineSchema.find(schema => schema.queryScheme && schema.queryScheme.canEnable);
            if (schemeConfig && schemeConfig.queryScheme && schemeConfig.queryScheme.relatedClass && schemeConfig.queryScheme.relatedClass.length) {
                const relatedClass = schemeConfig.queryScheme.relatedClass[0];

                const relateDom = this.domService.getNodeByIdPath(rootComponentJson, relatedClass.path);
                if (relateDom) {
                    if (relateDom.appearance && relateDom.appearance.class) {
                        relateDom.appearance.class = relateDom.appearance.class.replace(relatedClass.class, '');
                    }
                }


            }

            // 清除属性面板并刷新界面
            this.cmpInstance.emit('clearPropertyPanel');
            this.refreshFormService.refreshFormDesigner.next();
        });

    }
}

